home *** CD-ROM | disk | FTP | other *** search
- // CStrWnd.cpp
-
- // See CStrWnd.h for a definition of what the
- // class CStrWnd does
-
- #include "stdhdr.h"
- #include "test_r.h"
- #include "cstrwnd.h"
- #include "strdetab.h"
-
- CStrWnd::CStrWnd (const char * window_name)
- {
- VERIFY (LoadAccelTable ("CStrWndAccelTable"));
- VERIFY (Create (NULL, window_name,
- WS_CHILD | WS_VSCROLL, rectDefault,
- NULL));
- SetFocus ();
- current_first_row = 0; current_first_col = 0;
- h_scroll_flag = 0;
- length_of_longest_line = 0;
- }
-
- BEGIN_MESSAGE_MAP (CStrWnd, CMDIChildWnd)
- ON_WM_PAINT ()
- ON_WM_VSCROLL ()
- ON_WM_HSCROLL ()
- ON_WM_KEYDOWN ()
-
- ON_COMMAND (CSW_DOC_START, OnDocStart)
- ON_COMMAND (CSW_DOC_END, OnDocEnd)
- ON_COMMAND (CSW_LINE_RIGHT, OnLineRight)
- ON_COMMAND (CSW_LINE_LEFT, OnLineLeft)
- END_MESSAGE_MAP ()
-
- afx_msg void CStrWnd::OnPaint ()
- {
- CPaintDC dc (this);
- // Use a fixed-pitch font for better presentation
- VERIFY (dc.SelectStockObject(OEM_FIXED_FONT) != NULL);
-
- // First find out number of lines in the window
- TEXTMETRIC tm;
- VERIFY (dc.GetTextMetrics (&tm));
- const int char_height = tm.tmHeight
- + tm.tmExternalLeading;
- const int char_width = tm.tmAveCharWidth;
- CRect rect;
- GetClientRect (rect);
- no_of_lines = rect.Height () / char_height;
- no_of_chars_in_line = rect.Width () / char_width;
-
- // Set up the tab stop positions
- const int tab_interval = 4;
- const int no_of_tabs = 120 / tab_interval;
- int char_tab_stops [no_of_tabs];
- for (int i = 0; i < no_of_tabs; i++)
- char_tab_stops [i] = (i + 1) * tab_interval;
-
- // Write a window_full of text
-
- for (int lc = 0;
- lc < no_of_lines
- && current_first_row + lc
- < text_buffer.GetSize ();
- lc++)
- {
- const int max_line_length = 256;
- char out_buf [max_line_length + 1];
- int line_length;
- // Convert tabs to spaces
- strdetab (out_buf, max_line_length,
- text_buffer [current_first_row + lc],
- no_of_tabs, char_tab_stops,
- &line_length);
- // Get pointer to first char in line for output
- const char * first_char = out_buf
- + current_first_col;
- // Update record of longest line length
- if (length_of_longest_line < line_length)
- length_of_longest_line = line_length;
- // Call up horizontal scroll bar if needed
- if (line_length > no_of_chars_in_line)
- h_scroll_flag = 1;
- dc.TextOut (0, lc * char_height, first_char,
- line_length - current_first_col);
- }
- if (h_scroll_flag) ShowScrollBar (SB_HORZ, TRUE);
- }
-
- afx_msg void CStrWnd::OnVScroll (UINT nSBCode,
- UINT npos,
- CScrollBar * pBar)
- {
- int min_scroll_pos, max_scroll_pos,
- max_index = text_buffer.GetSize () - 1,
- scrolled = 1;
- if (max_index < 0) max_index = 0;
- // Cater for no lines in text_buffer
- switch (nSBCode)
- {
- case SB_LINEDOWN:
- current_first_row++; break;
- case SB_PAGEDOWN:
- current_first_row += no_of_lines - 1; break;
- case SB_LINEUP:
- current_first_row--; break;
- case SB_PAGEUP:
- current_first_row -= no_of_lines - 1; break;
- case SB_THUMBPOSITION:
- GetScrollRange (SB_VERT, &min_scroll_pos,
- &max_scroll_pos);
- current_first_row =
- (max_index * (npos - min_scroll_pos))
- / (max_scroll_pos - min_scroll_pos);
- break;
- default:
- // We did nothing, so do not update the window!
- scrolled = 0; break;
- }
-
- if (scrolled)
- {
- // Now make sure that the current row is in range
- if (current_first_row < 0) current_first_row = 0;
- if (current_first_row > max_index)
- current_first_row = max_index;
- Invalidate (TRUE);
- SetVerticalScroll ();
- UpdateWindow ();
- }
- }
-
- afx_msg void CStrWnd::OnHScroll (UINT nSBCode,
- UINT npos,
- CScrollBar * pBar)
- {
- int min_scroll_pos, max_scroll_pos,
- scrolled = 1;
- GetScrollRange (SB_VERT, &min_scroll_pos,
- &max_scroll_pos);
- switch (nSBCode)
- {
- case SB_LINERIGHT:
- current_first_col++; break;
- case SB_PAGERIGHT:
- current_first_col += 10; break;
- case SB_LINELEFT:
- current_first_col--; break;
- case SB_PAGELEFT:
- current_first_col -= 10; break;
- case SB_LEFT:
- current_first_col = 0; break;
- case SB_RIGHT:
- current_first_col = length_of_longest_line - 1;
- break;
- case SB_THUMBPOSITION:
- current_first_col =
- ((length_of_longest_line - 1)
- * (npos - min_scroll_pos))
- / (max_scroll_pos - min_scroll_pos);
- break;
- default:
- // We did nothing, so do not update window!
- scrolled = 0; break;
- }
-
- if (scrolled)
- {
- // Now ensure that we are within limits
- if (current_first_col < 0) current_first_col = 0;
- if (current_first_col >= length_of_longest_line)
- current_first_col = length_of_longest_line - 1;
- Invalidate (TRUE);
- if (h_scroll_flag)
- SetScrollPos (SB_HORZ,
- ((max_scroll_pos - min_scroll_pos)
- * current_first_col)
- / (length_of_longest_line -1)
- + min_scroll_pos,
- TRUE);
- UpdateWindow ();
- }
- }
-
- afx_msg void CStrWnd::OnKeyDown (UINT nChar,
- UINT nRepCnt,
- UINT nFlags)
- {
- switch (nChar)
- {
- case VK_DOWN:
- OnVScroll (SB_LINEDOWN, 0, NULL); break;
- case VK_NEXT: // Page down
- OnVScroll (SB_PAGEDOWN, 0, NULL); break;
- case VK_UP:
- OnVScroll (SB_LINEUP, 0, NULL); break;
- case VK_PRIOR: // Page up
- OnVScroll (SB_PAGEUP, 0, NULL); break;
- case VK_LEFT:
- OnHScroll (SB_LINELEFT, 0, NULL); break;
- case VK_HOME:
- OnHScroll (SB_LEFT, 0, NULL); break;
- case VK_RIGHT:
- OnHScroll (SB_LINERIGHT, 0, NULL); break;
- case VK_END:
- OnHScroll (SB_RIGHT, 0, NULL); break;
- }
- }
-
- afx_msg void CStrWnd::OnDocStart ()
- {
- int min_scroll_pos, max_scroll_pos;
- GetScrollRange (SB_VERT, &min_scroll_pos,
- &max_scroll_pos);
- Invalidate (TRUE);
- current_first_row = 0;
- SetScrollPos (SB_VERT, min_scroll_pos, TRUE);
- UpdateWindow ();
- }
-
- afx_msg void CStrWnd::OnDocEnd ()
- {
- int min_scroll_pos, max_scroll_pos;
- GetScrollRange (SB_VERT, &min_scroll_pos,
- &max_scroll_pos);
- Invalidate (TRUE);
- current_first_row = text_buffer.GetUpperBound () - 4;
- // Leave 4 lines on the screen
- if (current_first_row < 0) current_first_row = 0;
- SetScrollPos (SB_VERT, max_scroll_pos, TRUE);
- UpdateWindow ();
- }
-
- afx_msg void CStrWnd::OnLineRight ()
- {OnHScroll (SB_PAGERIGHT, 0, NULL);}
-
- afx_msg void CStrWnd::OnLineLeft ()
- {OnHScroll (SB_PAGELEFT, 0, NULL);}
-
- void CStrWnd::UpdateScreen ()
- {
- current_first_row = text_buffer.GetUpperBound ()
- - no_of_lines;
- if (current_first_row < 0) current_first_row = 0;
- SetVerticalScroll ();
- Invalidate (TRUE);
- UpdateWindow ();
- }
-
- void CStrWnd::SetVerticalScroll ()
- {
- int min_scroll_pos, max_scroll_pos,
- max_index = text_buffer.GetUpperBound ();
- GetScrollRange (SB_VERT, &min_scroll_pos,
- &max_scroll_pos);
- SetScrollPos (SB_VERT,
- ((max_scroll_pos - min_scroll_pos )
- * current_first_row)
- / ((max_index > 0) ? max_index : 1)
- + min_scroll_pos,
- TRUE);
- }
-